/*
 *  Copyright (c) 2012 Brandon Ellenberger
 *
 *  This file is part of OpSatPlan.
 *
 *  OpSatPlan is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  OpSatPlan is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with OpSatPlan.  If not, see <http://www.gnu.org/licenses/>.
 */

namespace OpSatPlan.LexerParser{

using TUVienna.CS_CUP.Runtime;
using System;


%%

Digit=[0-9]
Alpha=[a-zA-Z]
AlphaNum=({Alpha}|{Digit})


Define=[dD][eE][fF][iI][nN][eE]
Domain=[dD][oO][mM][aA][iI][nN]
Requirements=[rR][eE][qQ][uU][iI][rR][eE][mM][eE][nN][tT][sS]
Typing=[tT][yY][pP][iI][nN][gG]
Types=[tT][yY][pP][eE][sS]
Predicates=[pP][rR][eE][dD][iI][cC][aA][tT][eE][sS]
Action=[aA][cC][tT][iI][oO][nN]
Parameters=[pP][aA][rR][aA][mM][eE][tT][eE][rR][sS]
Precondition=[pP][rR][eE][cC][oO][nN][dD][iI][tT][iI][oO][nN]
Effect=[eE][fF][fF][eE][cC][tT]
Problem=[pP][rR][oO][bB][lL][eE][mM]
Init=[iI][nN][iI][tT]
Objects=[oO][bB][jJ][eE][cC][tT][sS]
Object=[oO][bB][jJ][eE][cC][tT]
Goal=[gG][oO][aA][lL]
And=[aA][nN][dD]
Not=[nN][oO][tT]
Either=[eE][iI][tT][hH][eE][rR]
Strips=[sS][tT][rR][iI][pP][sS]
Identifiers=[iI][dD][eE][nN][tT][iI][fF][iI][eE][rR][sS]

Comment=;[^\n]*[\n]

Identifier = {Alpha}({AlphaNum}|_|-)*

Unprintable=[^\000-\037\177]

Whitespace=[\040\t]+

%implements TUVienna.CS_CUP.Runtime.Scanner
%function next_token
%type TUVienna.CS_CUP.Runtime.Symbol
%class PddlLexer

%eofval{
	return new Symbol(sym.EOF, new PddlToken(0,0));
%eofval}

%init{
	Position.reset();
%init} 

%%

\r { break; }

\n {Position.Line += 1; Position.Column = 1; break; }

{Whitespace} {Position.Column += yytext().Length; break; }

{Comment} {Position.Line += 1; Position.Column = 1; break; }

"(" {Position.setPosition(); Position.Column += 1; 
	return new Symbol(sym.LPAREN, 
		new PddlToken(Position.LineNumber, Position.ColumnNumber)); }

")" {Position.setPosition(); Position.Column += 1; 
	return new Symbol(sym.RPAREN, 
		new PddlToken(Position.LineNumber, Position.ColumnNumber)); }
		
"-" {Position.setPosition(); Position.Column += 1; 
	return new Symbol(sym.MINUS, 
		new PddlToken(Position.LineNumber, Position.ColumnNumber)); }

":" {Position.setPosition(); Position.Column += 1; 
	return new Symbol(sym.COLON, 
		new PddlToken(Position.LineNumber, Position.ColumnNumber)); }
		
"?" {Position.setPosition(); Position.Column += 1; 
	return new Symbol(sym.QUESTION, 
		new PddlToken(Position.LineNumber, Position.ColumnNumber)); }

{Define} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.DEFINE,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Domain} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.DOMAIN,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Requirements} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.REQUIREMENTS,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Typing} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.TYPING,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Types} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.TYPES,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Predicates} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.PREDICATES,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
				
{Action} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.ACTION,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Parameters} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.PARAMETERS,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Precondition} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.PRECONDITION,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Effect} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.EFFECT,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Init} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.INIT,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Problem} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.PROBLEM,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Objects} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.OBJECTS,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Object} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.OBJECT,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Goal} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.GOAL,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{And} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.AND,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Not} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.NOT,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Either} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.EITHER,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
{Strips} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.STRIPS,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
	
{Identifiers} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.IDENTIFIERS,
		new PddlReservedWordToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
			
{Identifier} {Position.setPosition(); Position.Column += yytext().Length;
	return new Symbol(sym.IDENTIFIER,
		new PddlIdentifierToken(yytext(), Position.LineNumber, Position.ColumnNumber));}
		
. {Position.setPosition(); Position.Column += yytext().Length;
   Console.WriteLine( Position.LineNumber + ":" + Position.ColumnNumber + " " +
   "\tERROR: UNRECOGNISED TOKEN(" + yytext() + ")");
   break;}